package org.uc3m.pfc.device;

import org.opencv.android.CameraBridgeViewBase;
import org.uc3m.pfc.configuration.ConfigurationReader;
import org.uc3m.pfc.data.Action;
import org.uc3m.pfc.data.Device;
import org.uc3m.pfc.data.House;
import org.uc3m.pfc.data.Zone;
import org.uc3m.pfc.http.HttpHelper;
import org.uc3m.pfc.lifecycle.LifeCycle;
import org.uc3m.pfc.lifecycle.State;
import org.uc3m.pfc.ui.GuiUtils;

import android.content.Context;

/**
 * 
 * @author esteban
 *
 */
public final class DeviceManager extends LifeCycle implements IDeviceManager {
	
	// Class fields *******************************************************
	
	/** Static instance. */
	private static IDeviceManager instance;
	
	/** Data model object. */
	private House house;
	
	/** IP address server . */
	private String ip = "127.0.0.1";
	/** Port of server. */
	private int port = 8080;
	
	/** Helper for http connections. */
	private HttpHelper httpHelper;
	/** Reader for configuration file. */
	private ConfigurationReader configurationReader;
	
	/** Utility for UI management. */
	private GuiUtils guiUtils;
	
	
    // Constructor *******************************************************
	
	/**
	 * Private default constructor.
	 */
	private DeviceManager() {
		
		guiUtils = GuiUtils.getInstance();
		configurationReader = ConfigurationReader.getReader();

		httpHelper = HttpHelper.getHelper();
		
		start();

		setState(State.stopped);
		
	}
	
	/** Start the manager. */
	private void start() {

		// get the data model object. 
		house = initDynamicDataModel(guiUtils.getContext());
	}

	/**
	 * Get the data model from the configuration file.
	 * 
	 * @param context of activity, get assets
	 * @return house data object
	 */
	private House initDynamicDataModel(final Context context) {
		
		return configurationReader.loadConfiguration(context);
	}

	/**
	 * Get the instance.
	 * 
	 * @return static instance
	 */
	public static IDeviceManager getInstance() {
		
		if (instance == null) {
			instance = new DeviceManager();
		}
		
		return instance;
	}
	
	
    // IDeviceManager methods **********************************************
	
	@Override
	public Device getDevice(final int deviceId) {
		
		if (house == null) {
			return null;
		}
		
		// TODO fixed
		int zoneId = 1;
		Device deviceAux = null;
		
		for (Zone zone : house.getZones()) {
			if (zone.getId() == zoneId) {
				for (Device device : zone.getDevices()) {
					if (device.getId() == deviceId) {
						deviceAux = device;
						break;
					}
				}
			}
			if (deviceAux != null) {
				break;
			}
		}
		
		if (deviceAux == null) {
			// TODO error
		}
		
		// TODO Auto-generated method stub
		return deviceAux;
	}

	@Override
	public String executeFunction(final Device device, final Action action) {

		String message = null;
		
		setState(State.requesting);
		
		boolean resultOk = false; 

		String url = getUrl(device, action);
		
		String content = httpHelper.getContentFromUrl(url);
		
		resultOk = parseResponse(content);
		
		// TODO handle request, strings from resources
		
		if (resultOk) {
			
			message = "Comando correcto";
			
		} else {
			message = "Comando incorrecto, " 
					+ "fallo en el servidor";
		}
		
		setState(State.stopped);
		
		return message;
	}

	
    // Private methods ****************************************************
	
	/**
	 * Parse the http response.
	 * 
	 * @param content http content
	 * @return string with the response
	 */
	private boolean parseResponse(final String content) {

		// TODO response more complex, error type, exception, ...
//		if (result != null && result.contains("OK")) {
//			resultOk = true;
//		}
		boolean resultOk = false;
		
		if (content != null) {
			
			if (!content.contains("OK")) {
				resultOk = true;
			} 
			
		}
		
		return resultOk;
	}

	/**
	 * Compose the url from the device and action.
	 * 
	 * @param device selected
	 * @param action selected
	 * 
	 * @return url for the http request
	 */
	private String getUrl(final Device device, final Action action) {
		
		// example
		// 'http://IP_HOST:PORT/action.html?deviceId=LUZ1&action=ON' 
		
		String url = 
				"http://"
				+ ip + ":" + port
				+ "/action.html?"
				+ "deviceId=" 
				+ device.getUrl()
				+ "&"
				+ "action="
				+ action.getUrl();
		
		return url;
	}

	@Override
	public String getIp() {
		return ip;
	}

	@Override
	public int getPort() {
		return port;
	}
	
	@Override
	public void setIp(final String pip) {
		this.ip = pip;
	}
	
	@Override
	public void setPort(final int pport) {
		this.port = pport;
	}

	@Override
	public void setState(final State pstate) {
		super.setState(pstate);
		
		switch (pstate) {
		case requesting:
			CameraBridgeViewBase.enableHttpLink = true;
						
			break;
		case stopped:

			CameraBridgeViewBase.enableHttpLink = false;
						
			break;

		default:

			CameraBridgeViewBase.enableHttpLink = false;
						
			break;
		}
	}

	
}
